import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import * as cookieParser from 'cookie-parser';
import * as session from 'express-session';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
// import helmet from 'helmet';
import rateLimit from 'express-rate-limit';
import * as Chalk from 'chalk';
// import * as bodyParser from 'body-parser';

//引入
import { NestExpressApplication } from '@nestjs/platform-express';
import { join } from 'path';
//引入日志中间件
import { logger } from './middleware/logger/logger.middleware';
import * as express from 'express';

import { TransformInterceptor } from './interceptor/transform/transform.interceptor';
import { HttpExceptionFilter } from './filter/http-exception/http-exception.filter';
import { AllExceptionsFilter } from './filter/any-exception/any-exception.filter';
import { ConfigService } from '@nestjs/config';
import { Logger } from './utils/log4js';
// import { ValidationPipe } from '@nestjs/common';

async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(AppModule);

  //注册cookie
  app.use(cookieParser("dmyxs")); //加密密码

  //配置session
  app.use(
    session({
      name: 'c.sid', // 返回客户端的 key 的名称，默认为 connect.sid,也可以自己设置
      secret: 'dmyxs', // 密钥，一个 String 类型的字符串，作为服务器端生成 session 的签名
      resave: false, // 强制保存 session 即使它并没有变化,。默认为 true。建议设置成 false
      saveUninitialized: true, // 强制将未初始化的 session 存储。当新建了一个 session 且未设定属性或值时，它就处于未初始化状态。在设定一个cookie前，这对于登陆验证，减轻服务端存储压力，权限控制是有帮助的。（默 认：true）。
      cookie: { maxAge: 1000 * 60 * 60 * 24 }, // cookie配置，设置返回到前端 key 的属性，默认值为{ path: ‘/’, httpOnly: true, secure: false, maxAge: null }。
      rolling: true, // 在每次请求时强行设置 cookie，重置 cookie 过期时间（默认：false）
    }),
  );

  const config = app.get(ConfigService);
  app.useStaticAssets(join(__dirname, '../', '/static'), {
    prefix: '/static/',
  }); // http://localhost:10000/xxx.png
  app.useStaticAssets(join(__dirname, '../', '/web'), {
    prefix: '/nest-web/',
  }); // http://localhost:10000/xxx.html
  app.useStaticAssets(join(__dirname, '../', '/uploads'), {
    prefix: '/uploads/',
  }); // http://localhost:10000/uploads/xxx.txt
  //模板引起配置
  app.setBaseViewsDir(join(__dirname, '/views')); //模板引擎目录
  app.setViewEngine('ejs'); //模板渲染引擎

  // web 安全，防常见漏洞
  // app.use(helmet());

  // 设置访问频率
  app.use(
    rateLimit({
      windowMs: 5 * 60 * 1000, // 5分钟
      max: 1000, // 限制5分钟内最多只能访问1000次
    }),
  );

  // 防止跨站请求伪造
  // 设置 csrf 保存 csrfToken
  // app.use(csurf())

  //路径变成：localhost:10000/static/1.png
  // app.useStaticAssets('public', {
  //   prefix: '/static/',
  // });

  // app.useGlobalPipes(new ValidationPipe()); //开启一个全局验证管道

  app.use(express.json({ limit: '500mb' }));
  app.use(express.urlencoded({ extended: true, limit: '500mb' }));

  // 监听所有的请求路由，并打印日志
  app.use(logger);

  //全局使用拦截器
  app.useGlobalInterceptors(new TransformInterceptor());
  //全局使用过滤器
  // 过滤处理http异常
  app.useGlobalFilters(new AllExceptionsFilter());
  app.useGlobalFilters(new HttpExceptionFilter());

  const swaggerConfig = new DocumentBuilder()
    .setTitle('短文发布平台')
    .setDescription('使用nest书写的常用性接口')
    .setVersion('1.0')
    .addTag('nest swagger')
    .build();
  const document = SwaggerModule.createDocument(app, swaggerConfig);

  SwaggerModule.setup('api', app, document);
  app.enableCors(); //开启跨域访问
  const port = config.get('app.port');
  await app.listen(port);

  Logger.log(
    Chalk.green(`nest-vue-short-passage 服务启动成功 `),
    Chalk.yellow(`http://localhost:${port}/`),
    '\n',
  );
}
bootstrap();
